﻿// -------------------------------------------------------------------------
//    @FileName         :    NFWelfareConfOne.h
//    @Author           :    gaoyi
//    @Date             :    2025-06-30
//    @Email			:    445267987@qq.com
//    @Module           :    NFWelfareConfOne
//
// -------------------------------------------------------------------------

#pragma once

#include "E_Welfare.nanopb.h"
#include "proto_svr_world.nanopb.h"

/**
 * @brief 单个福利配置类
 * 
 * 管理单个福利活动的完整配置信息，包括：
 * - 福利基础信息（ID、类型、循环类型等）
 * - 福利节点配置（奖励、条件等）
 * - 时间管理（开启时间、结束时间、展示时间等）
 * - 配置验证和时间计算
 * 
 * 该类负责福利配置的加载、验证、时间计算等核心逻辑。
 */
class NFWelfareConfOne
{
public:
    /**
     * @brief 构造函数
     */
    NFWelfareConfOne();

    /**
     * @brief 析构函数
     */
    ~NFWelfareConfOne();

    /**
     * @brief 创建初始化
     * @return 成功返回0，失败返回错误码
     */
    int CreateInit();

    /**
     * @brief 恢复初始化
     * @return 成功返回0，失败返回错误码
     */
    int ResumeInit();

public:
    /**
     * @brief 获取福利ID
     * @return 福利ID
     */
    uint64_t GetWelfareID() const { return m_confOne.m_stWelfareDesc.m_welfareId; }

    /**
     * @brief 获取最后修改时间
     * @return Unix时间戳
     */
    uint32_t GetLastChangeUnixSec() const { return m_confOne.m_dwLastChangeUnixSec; }

    /**
     * @brief 设置最后修改时间
     * @param dwTime Unix时间戳
     */
    void SetLastChangeUnixSec(uint32_t dwTime) { m_confOne.m_dwLastChangeUnixSec = dwTime; }

    /**
     * @brief 获取福利配置（常量版本）
     * @return 福利配置引用
     */
    const E_Welfare& GetWelfareConf() const { return m_confOne.m_stWelfareDesc; }

    /**
     * @brief 获取福利配置（可修改版本）
     * @return 福利配置引用
     */
    E_Welfare& GetWelfareConf() { return m_confOne.m_stWelfareDesc; }

    /**
     * @brief 获取节点数量
     * @return 节点数量
     */
    int GetNodeNum() const { return m_confOne.m_astWelfareNodeDesc.size(); }

    /**
     * @brief 根据节点ID查找节点配置
     * @param dwNodeId 节点ID
     * @return 节点配置指针，未找到返回nullptr
     */
    const E_WelfareNode* FindNodeByNodeID(uint32_t dwNodeId) const;

    /**
     * @brief 根据节点类型获取第一个匹配的节点
     * @param nodeType 节点类型
     * @param pNodeDesc 输出参数，返回节点配置指针
     * @return 成功返回0，失败返回错误码
     */
    int GetFirstNodeDescByType(int nodeType, const E_WelfareNode*& pNodeDesc) const;

    /**
     * @brief 检查福利是否可以完成
     * @return true表示可以完成，false表示不可完成
     */
    bool CanComplete() const { return m_confOne.m_bCanComplete; }

    PBWelfareConfOne& GetConf() { return m_confOne; }
    const PBWelfareConfOne& GetConf() const { return m_confOne; }
public:
    /**
     * @brief 重置配置数据
     */
    void Reset();

    /**
     * @brief 检查并计算配置
     * @param dwGameOpenDayBeginUnixSec 游戏开服时间
     * @param bIsIdIp 是否为ID IP
     * @param iWorldId 世界ID
     * @return 成功返回0，失败返回错误码
     */
    int CheckAndCalcConf(uint32_t dwGameOpenDayBeginUnixSec, bool bIsIdIp, int iWorldId);

    /**
     * @brief 设置配置数据
     * @param ullWelfareID 福利ID
     * @param dwChangeUnixSec 修改时间
     * @param dwGameOpenDayBeginUnixSec 游戏开服时间
     * @param iWorldID 世界ID
     * @return 成功返回0，失败返回错误码
     */
    int SetConfData(uint64_t ullWelfareID, uint32_t dwChangeUnixSec, uint32_t dwGameOpenDayBeginUnixSec, int iWorldID);

private:
    /**
     * @brief 检查并设置开启时间配置
     * @param iWorldId 世界ID
     * @param bIsIdIp 是否为ID IP
     * @return 成功返回0，失败返回错误码
     */
    int CheckAndSetOpenTimeConf(int iWorldId, bool bIsIdIp);

    /**
     * @brief 检查是否包含指定ID（带类型）
     * @param strIdRangeList ID范围列表字符串
     * @param iWorldId 世界ID
     * @param bContain 输出参数，是否包含
     * @return 成功返回0，失败返回错误码
     */
    int CheckContainIdWithType(const std::string& strIdRangeList, int iWorldId, bool& bContain);

    /**
     * @brief 检查是否包含指定ID
     * @param strIdRangeList ID范围列表字符串
     * @param iWorldId 世界ID
     * @param bContain 输出参数，是否包含
     * @return 成功返回0，失败返回错误码
     */
    int CheckContainId(const std::string& strIdRangeList, int iWorldId, bool& bContain);

    /**
     * @brief 检查并计算开启时间范围
     * @param stUnixTimeRangeOpen 开启时间范围
     * @param stIntRangeGameOpen 游戏开启天数范围
     * @param dwGameOpenDayBeginUnixSec 游戏开服时间
     * @param bIsIdip 是否为ID IP
     * @param startTimeGameSvrOpenDay 开服相对开始时间
     * @param endTimeGameSvrOpenDay 开服相对结束时间
     * @param iOpenTimeGameSvrOpenDayAdjustType 开启时间调整类型
     * @param iCloseTimeGameSvrOpenDayAdjustType 关闭时间调整类型
     * @return 成功返回0，失败返回错误码
     */
    int CheckAndCalcOpenTimeRange(UnixTimeRange& stUnixTimeRangeOpen, const IntRange& stIntRangeGameOpen, uint32_t dwGameOpenDayBeginUnixSec, bool bIsIdip
                                  , const UnixTimeOne& startTimeGameSvrOpenDay, const UnixTimeOne& endTimeGameSvrOpenDay, int32_t iOpenTimeGameSvrOpenDayAdjustType, int32_t iCloseTimeGameSvrOpenDayAdjustType);

    /**
     * @brief 检查并计算展示时间范围
     * @param stUnixTimeRangeShow 展示时间范围
     * @param stUnixTimeRangeOpen 开启时间范围
     * @param bIsIdip 是否为ID IP
     * @return 成功返回0，失败返回错误码
     */
    int CheckAndCalcShowTimeRange(UnixTimeRange& stUnixTimeRangeShow, const UnixTimeRange& stUnixTimeRangeOpen, bool bIsIdip);

    /**
     * @brief 计算是否可以完成
     * @return 成功返回0，失败返回错误码
     */
    int CalcCanComplete();

    /**
     * @brief 是否跳过检查直接设置为可完成
     * @return true表示跳过检查，false表示需要检查
     */
    bool IsSkipAndDirSetCanCompleteTrue() const;

private:
    /// 福利配置数据
    PBWelfareConfOne m_confOne;
};
